﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Framework.Core.Cryptography
{
    public sealed class AssymetricEncryptionWriter : IDisposable
    {
        private readonly RSAParameters publicKey;
        private readonly RSACryptoServiceProvider rsa;
        private readonly BinaryWriter writer;

        private AssymetricEncryptionWriter(Stream destination)
        {
            writer = new BinaryWriter(destination);
        }

        public AssymetricEncryptionWriter(Stream destination, string application, string user)
            : this(destination, application, user, new RsaCryptoServiceProviderFactory())
        {
        }

        private AssymetricEncryptionWriter(Stream destination,
                                           string application,
                                           string user,
                                           IRsaCryptoServiceProviderFactory rsaCryptoServiceProviderFactory)
            : this(destination)
        {
            rsa = rsaCryptoServiceProviderFactory.Create(application, user);
            publicKey = rsa.ExportParameters(false);
        }

        public AssymetricEncryptionWriter(Stream destination, Stream publicKeyStream)
            : this(destination)
        {
            rsa = new RSACryptoServiceProvider(2048);
            using (var reader = new StreamReader(publicKeyStream))
            {
                publicKeyStream.Flush();
                publicKeyStream.Seek(0, SeekOrigin.Begin);
                rsa.FromXmlString(reader.ReadToEnd());
                publicKey = rsa.ExportParameters(false);
            }
        }

        void IDisposable.Dispose()
        {
            ((IDisposable)writer).Dispose();
            ((IDisposable)rsa).Dispose();
        }

        public void Write(string value)
        {
            rsa.ImportParameters(publicKey);
            writer.Write(rsa.Encrypt(Encoding.UTF8.GetBytes(value), false));
        }
    }
}
